package cscie160.hw3;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import cscie160.hw3.ElevatorFullException;
import cscie160.hw3.Floor;

public class Elevator {
	private static int direction;
	public static final int MAX_CAPACITY = 10;
	public static final int FLOORS = 7;
	private static List<Passenger> waitingToUnload = new CopyOnWriteArrayList<Passenger>();

	public Elevator() {
	}

	public static List<Passenger> getWaitingToUnload() {
		return waitingToUnload;
	}

	public void addWaitingToUnload(Passenger passenger) {
		waitingToUnload.add(passenger);
	}

	public static void removeWaitingToUnload(Passenger passenger) {
		waitingToUnload.remove(passenger);
	}

	public void move() throws ElevatorFullException {
		boolean stop = false;
		if (Floor.getCurrentFloor() == 1) {
			direction = 1;
		}
		if (Floor.getCurrentFloor() == FLOORS) {
			direction = -1;
		}
		if (!waitingToUnload.isEmpty()) {
			for (Passenger v : waitingToUnload) {
				if (v.getDestFloor() == Floor.getCurrentFloor()) {
					stop = true;
				}
			}
		}
		if (!Floor.getUpService().isEmpty() && direction == 1) {
			for (Passenger v : Floor.getUpService()) {
				if (v.getCurrFloor() == Floor.getCurrentFloor()) {
					stop = true;
				}
			}
		}
		if (!Floor.getDownService().isEmpty() && direction == -1) {
			for (Passenger v : Floor.getDownService()) {
				if (v.getCurrFloor() == Floor.getCurrentFloor()) {
					stop = true;
				}
			}
		}
		if (stop) {
			stop();
			System.out.println(this);
		}
		Floor.setCurrentFloor(Floor.getCurrentFloor() + direction);
	}

	private void stop() throws ElevatorFullException {
		if (direction == 1) {
			System.out.println("Going up");
		} else {
			System.out.println("Going down");
		}
		System.out.println("Stopping on floor " + Floor.getCurrentFloor());
		Floor.unloadPassengers();
	}

	public static void boardPassengers() throws ElevatorFullException {
		if (direction == 1) {
			if (!Floor.getUpService().isEmpty()) {
				for (Passenger v : Floor.getUpService()) {
					if (v.getCurrFloor() == Floor.getCurrentFloor()) {
						if (waitingToUnload.size() >= MAX_CAPACITY) {
							try {
								throw new ElevatorFullException();
							} catch (ElevatorFullException e) {
								System.out
										.println("Elevator won't fit everyone.");
							}
						} else {
							waitingToUnload.add(v);
							Floor.removeUpService(v);
						}
					}
				}
			}
		} else {
			if (!Floor.getDownService().isEmpty()) {
				for (Passenger v : Floor.getDownService()) {
					if (v.getCurrFloor() == Floor.getCurrentFloor()) {
						if (waitingToUnload.size() >= MAX_CAPACITY) {
							try {
								throw new ElevatorFullException();
							} catch (ElevatorFullException e) {
							}
						} else {
							waitingToUnload.add(v);
							Floor.removeDownService(v);
						}
					}
				}
			}
		}
	}

	public void registerRequest(int fromFloor, int toFloor) {
		if (fromFloor < toFloor) {
			Floor.addUpService(new Passenger(fromFloor, toFloor));
		} else {
			if (fromFloor > toFloor) {
				Floor.addDownService(new Passenger(fromFloor, toFloor));
			}
		}
	}

	public String toString() {
		return "Currently " + waitingToUnload.size() + " passengers onboard \n";
	}

	public static void main(String[] args) throws ElevatorFullException {
		Elevator elevator = new Elevator();
		elevator.registerRequest(2, 4);
		elevator.registerRequest(5, 3);
		elevator.registerRequest(3, 4);
		elevator.registerRequest(5, 1);
		elevator.registerRequest(6, 7);
		elevator.registerRequest(7, 3);
		elevator.registerRequest(2, 4);
		elevator.registerRequest(5, 3);
		elevator.registerRequest(3, 4);
		elevator.registerRequest(5, 1);
		elevator.registerRequest(6, 7);
		elevator.registerRequest(7, 3);
		elevator.registerRequest(2, 4);
		elevator.registerRequest(5, 3);
		elevator.registerRequest(3, 4);
		elevator.registerRequest(5, 1);
		elevator.registerRequest(6, 7);
		elevator.registerRequest(7, 3);
		elevator.registerRequest(2, 4);
		elevator.registerRequest(5, 3);
		elevator.registerRequest(3, 4);
		elevator.registerRequest(5, 1);
		elevator.registerRequest(6, 7);
		elevator.registerRequest(7, 3);

		for (int i = 0; i <= 25; i++) {
			elevator.move();
		}
		System.out.println("Resident queue: " + Floor.getResident().size());
		System.out.println("Upservice queue: " + Floor.getUpService().size());
		System.out.println("Downservice queue: "
				+ Floor.getDownService().size());
		System.out.println("Elevator queue: " + waitingToUnload.size());
	}
}

// @TODO:
// 1. implement arive() method